<?php
namespace Sonkwl\UsePHP;

use Sonkwl\UsePHP\mysqler;
use Sonkwl\UsePHP\jsoner;

class design{
    //配置清单
    private static $config=array();
    public static function SetConfig($arr){
        if(!isset($arr["title"])){
            jsoner::Response(array("res"=>"NG","message"=>"design::config中没有定义title"));
        }
        if(!isset($arr["baseurl"])){
            jsoner::Response(array("res"=>"NG","message"=>"design::config中没有定义baseurl"));
        }
        self::$config=$arr;
        return __CLASS__;
    }
    //创建处理
    public static function Create($arr){
        if(isset($_GET["config"])){
            $arr=explode(",",$_GET["config"]);
        }
        if(in_array("design",$arr)){
            self::CreateDesign();
        }
        if(in_array("document",$arr)){
            self::CreateDocument();
        }
        if(in_array("database",$arr)){
            self::CreateDataBase("");
        }
        if(in_array("databaseadd",$arr)){
            self::CreateDataBase("add");
        }
        if(in_array("model",$arr)){
            self::CreateModel();
        }
        if(in_array("controlinit",$arr)){
            self::CreateControl("init");
        }
        if(in_array("control",$arr)){
            self::CreateControl("");
        }
        if(!isset($_GET["config"])){
            header("location:design/index.html");
        }
    }
    //创建Design
    public static function CreateDesign(){
        if(is_dir("design")){
            return;
        }
        mkdir("design",0777);
        $dir=__DIR__."/design/";
        foreach(scandir($dir) as $file){
            if($file=="." || $file==".."){
                continue;
            }
            if($file=="config.json"){
                continue;
            }
            $fileordir=$dir."/".$file;
            if(is_dir($fileordir)){
                mkdir("design/".$file);
                continue;
            }
            file_put_contents("design/".$file,file_get_contents($fileordir));
        }
        // 配置文件config.json
        $config="{\n";
        $config.="    \"title\":\"".self::$config["title"]."\",\n";
        $config.="    \"datatype\":[\"string\",\"int\",\"datetime\",\"array\"],\n";
        $config.="    \"baseurl\":\"".self::$config["baseurl"]."\"\n";
        $config.="}";
        file_put_contents("design/config.json",$config);
        file_put_contents("design/database/database.json","[]");
        file_put_contents("design/dictionary/dictionary.json",file_get_contents($dir."dictionary/dictionary.json"));
        file_put_contents("design/interface/interface.json","[]");
        echo '<hr>Seccuss创建design';
    }
    //创建document
    public static function CreateDocument(){
        if(!is_dir("document")){
            mkdir("document",0777);
        }
        if(!is_dir("document/interface")){
            mkdir("document/interface",0777);
        }
        if(!is_dir("document/database")){
            mkdir("document/database",0777);
        }
        if(!is_dir("document/dictionary")){
            mkdir("document/dictionary",0777);
        }
        $dir="design/";
        foreach(scandir($dir) as $file){
            if($file=="." || $file==".."){
                continue;
            }
            if($file=="index.js"){
                continue;
            }
            if($file=="index_release.js"){
                file_put_contents("document/index.js",file_get_contents("design/index_release.js"));
                continue;
            }
            $fileordir=$dir."/".$file;
            if(is_dir($fileordir)){
                if(!is_dir("document/".$file)){
                    mkdir("document/".$file,0777);
                }
                file_put_contents("document/".$file."/".$file.".json",file_get_contents("design/".$file."/".$file.".json"));
                continue;
            }
            file_put_contents("document/".$file,file_get_contents($fileordir));
        }
        echo '<hr>Seccuss创建document';
    }
    //创建control文件
    public static function CreateDataBase($op){
        $sql=self::CreateSql($op);
        if($sql==""){
            return;
        }
        // echo $sql;
        try{
            $db=mysqler::GetPDO();
            $db->exec($sql);
            echo '<hr>Seccuss创建table';
        }catch(Exception $e){
            echo '{"res":"NG","message":"创建table失败:'.$e->getMessage().'"}';
        }
    }
    //构建sql
    public static function CreateSql($op){
        if(!is_file("design/database/database.json")){
            jsoner::Response(array("res"=>"NG","message"=>"database.json不存在，请先执行design命令"));
        }
        $sql="";
        $database=file_get_contents("design/database/database.json");
        $database=json_decode($database,true);
        if(!is_array($database)){
            jsoner::Response(array("res"=>"","message"=>"design/database/database.json文件数据异常，请检查"));
        }
        foreach ($database as $key=>$table) {
            $table_name=$table["table"];
            if($op=="add"){
                //新增table,不影响已新增table
                $sql.="create table if not exists {$table_name} (\n";
                foreach ($table["column"] as $column => $rule) {
                    $sql.=$column." ".$rule["type"]." ".$rule["index"].",";
                }
            }else{
                $sql.="drop table if exists {$table_name};\n";
                $sql.="create table {$table_name} (\n";
                foreach ($table["column"] as $column => $rule) {
                    $sql.=$column." ".$rule["type"]." ".$rule["index"].",";
                }
            }
            
            $sql=trim($sql,",");
            $sql.=")charset=utf8;\n";
        }
        return $sql;
    }

    //创建control
    public static function CreateControl($init){
        if(!is_file("design/interface/interface.json")){
            jsoner::Response(array("res"=>"NG","message"=>"interface.json不存在，请先执行design命令"));
        }
        if(!is_dir("control")){
            mkdir("control",0777);
        }
        if(!is_dir("control/get")){
            mkdir("control/get",0777);
        }
        if(!is_dir("control/post")){
            mkdir("control/post",0777);
        }
        if(!is_dir("control/validate")){
            mkdir("control/validate",0777);
        }
        $interface=file_get_contents("design/interface/interface.json");
        $interface=json_decode($interface,true);
        if(!is_array($interface)){
            jsoner::Response(array("res"=>"","message"=>"design/interface/interface.json文件数据异常，请检查"));
        }
        self::CreateIndexFile();
        self::CreateControlFile($interface,$init);
    }
    //生成index.php
    public static function CreateIndexFile(){
        if(is_file("control/index.php")){
            return;
        }
        $file="<?php\n";
        $file.="//项目入口文件\n";
        $file.="include \$_SERVER['DOCUMENT_ROOT'].'/vendor/autoload.php';\n";
        $file.="use \Sonkwl\UsePHP\autoroute;\n";
        $file.="use \Sonkwl\UsePHP\jwter;\n";
        $file.="use \Sonkwl\UsePHP\mysqler;\n";
        $file.="use \Sonkwl\UsePHP\autocontrol;\n\n";
        $file.="mysqler::Set('host','".mysqler::Get("host")."');\n";
        $file.="mysqler::Set('dbname','".mysqler::Get("dbname")."');\n";
        $file.="mysqler::Set('user','".mysqler::Get("user")."');\n";
        $file.="mysqler::Set('pwd','".mysqler::Get("pwd")."');\n\n";
        $file.="jwter::Set('version','V1');\n";
        $file.="jwter::Set('keyint','1');\n";
        $file.="jwter::Set('keystr','WHSS');\n";
        $file.="jwter::Set('exp',strtotime(\"+8 hours\",time()));\n";
        $file.="autoroute::ValidateRequest();\n";
        $file.="autoroute::Run();\n";
        $file.="?>\n";
        file_put_contents("control/index.php",$file);
    }
    //生成control所需文件
    public static function CreateControlFile($arr,$init){
        foreach ($arr as $key => $interface) {
            self::CreateValidateFile($interface);
            self::CreateProgramFile($interface,$init);
        }
    }
    //生成validate文件
    public static function CreateValidateFile($interface){
        $filename="control/validate/".strtolower($interface["method"])."-".$interface["url"].".php";
        $file="<?php\n";
        $file.="//".$interface["desc"]."\n";
        $file.="use \Sonkwl\UsePHP\jsoner;\n";
        $request=$interface["request"];
        foreach ($request as $key => $val) {
            $input="\$_".strtoupper($interface["method"])."[\"{$key}\"]";
            if($val["type"]=="array"){
                if($val["isMust"]!="是"){
                    $file.="if(isset({$input})){\n";
                    $file.="    if(!is_array({$input})){\n";
                    $file.="        jsoner::Response(array('res'=>'NG','message'=>'{$key}必须是数组'));\n";
                    $file.="    }\n";
                    $file.="    foreach({$input} as \$key=>\$value){\n";
                    $file=self::GetRegex($key,"\$value",$val["regex"],$file,"        ");
                    $file.="    }\n";
                    $file.="}\n";
                    continue;
                }
                $file.="if(!isset({$input})){\n";
                $file.="    jsoner::Response(array('res'=>'NG','message'=>'没有定义{$key}'));\n";
                $file.="}\n";
                $file.="if(!is_array({$input})){\n";
                $file.="    jsoner::Response(array('res'=>'NG','message'=>'{$key}必须是数组'));\n";
                $file.="}\n";
                $file.="foreach({$input} as \$key=>\$value){\n";
                $file=self::GetRegex($key,"\$value",$val["regex"],$file,"    ");
                $file.="}\n";
            }else{
                if($val["isMust"]!="是"){
                    $file.="if(isset({$input})){\n";
                    $file=self::GetRegex($key,$input,$val["regex"],$file,"    ");
                    $file.="}\n";
                    continue;
                }
                $file.="if(!isset({$input})){\n";
                $file.="    jsoner::Response(array('res'=>'NG','message'=>'没有定义{$key}'));\n";
                $file.="}\n";
                $file=self::GetRegex($key,$input,$val["regex"],$file,"");
            }
        }
        $file.="?>";
        file_put_contents($filename,$file);
        echo '<hr>Seccuss创建'.$filename;
    }
    //返回验证string
    public static function GetRegex($key,$input,$regex,$file,$space){
        if($regex=="int"){
            $file.=$space."if(!is_numeric({$input})){\n";
            $file.=$space."    jsoner::Response(array('res'=>'NG','message'=>'{$key}必须是数字'));\n";
            $file.=$space."}\n";
        }
        if(stristr($regex,"len")){
            $sub=explode(":",$regex);
            $min=$sub[1];
            $max=$sub[2];
            $file.=$space."if(strlen({$input})<{$min} || strlen({$input})>{$max}){\n";
            $file.=$space."    jsoner::Response(array('res'=>'NG','message'=>'{$key}的字数在{$min}~{$max}之间'));\n";
            $file.=$space."}\n";
        }
        if(stristr($regex,"/")){
            $regex=str_replace("\u4e00-\u9fa5","\x{4e00}-\x{9fa5}",$regex);
            $file.=$space."if(!preg_match(\"{$regex}u\",{$input})){\n";
            $file.=$space."    jsoner::Response(array('res'=>'NG','message'=>'{$key}的格式错误'));\n";
            $file.=$space."}\n";
        }
        return $file;
    }
    //生成program文件
    public static function CreateProgramFile($interface,$init){
        $filename="control/".strtolower($interface["method"])."/".$interface["url"].".php";
        if(is_file($filename) && $init==""){
            return;
        }
        $file="<?php\n";
        $file.="//@DESC ".$interface["desc"]."\n";
        $file.="//@METHOD ".$interface["method"]."\n";
        $file.="//@INPUT ";
        foreach ($interface["request"] as $key => $value) {
            $file.="{$key}:".$value["type"].",";
        }
        $file=trim($file,",")."\n";
        $file.="//@OUTPUT ";
        foreach ($interface["response"] as $key => $value) {
            $file.="{$key}:".$value["type"].",";
        }
        $file=trim($file,",")."\n";
        $file.="?>";
        file_put_contents($filename,$file);
        echo '<hr>Seccuss创建'.$filename;
    }
    //生成table model
    public static function CreateModel(){
        $dictionay=json_decode(file_get_contents("design/dictionary/dictionary.json"),true);
        $database=json_decode(file_get_contents("design/database/database.json"),true);
        if(!is_dir("model")){
            mkdir("model",0777);
        }

        foreach ($database as $key => $table) {
            $file="<?php\n";
            $file.="//@MODEL ".$table["table"]."\n";
            $file.="class ".$table["table"]."{\n";
            //遍历column
            foreach ($table["column"] as $column => $val) {
                $file.="    private static \${$column}=NULL;\n";
            }
            //__SET
            $file.="    public static function Set(\$k,\$v){\n";
            $file.="        if(property_exists(\"".$table["table"]."\",\$k)){\n";
            $file.="            self::\$\$k=\$v;\n";
            $file.="        }\n";
            $file.="    }\n";
            //新增
            $file.="    public static function Insert(){\n";
            $file.="        \$column=[];\n";
            $file.="        \$params=[];\n";
            $file.="        \$wenhao=[];\n";
            foreach ($table["column"] as $column => $val) {
                $file.="        if(!is_null(self::\${$column})){\n";
                $file.="            array_push(\$column,\"{$column}\");\n";
                $file.="            array_push(\$params,self::\${$column});\n";
                $file.="            array_push(\$wenhao,\"?\");\n";
                $file.="        }\n";
            }
            $file.="        \$sql=\"insert into ".$table["table"]."(\".implode(\",\",\$column).\") values(\".implode(\",\",\$wenhao).\")\";\n";
            $file.="        return [\"sql\"=>\$sql,\"params\"=>\$params];\n";
            $file.="    }\n";

            //删除
            $file.="    public static function Delete(){\n";
            $file.="        \$params=[];\n";
            $file.="        \$wenhao=[];\n";
            foreach ($table["column"] as $column => $val) {
                if(isset($dictionay[$column]) && $val["index"]!=""){
                    $file.="        if(!is_null(self::\${$column})){\n";
                    $file.="            array_push(\$params,self::\${$column});\n";
                    $file.="            array_push(\$wenhao,\"and {$column}=?\");\n";
                    $file.="        }\n";
                }
            }
            $file.="        \$sql=\"delete from ".$table["table"]." where 1=1 \".implode(\" \",\$wenhao).\";\";\n";
            $file.="        return [\"sql\"=>\$sql,\"params\"=>\$params];\n";
            $file.="    }\n";

            //更新
            $file.="    public static function Update(){\n";
            $file.="        \$params1=[];\n";
            $file.="        \$wenhao1=[];\n";
            $file.="        \$params2=[];\n";
            $file.="        \$wenhao2=[];\n";
            foreach ($table["column"] as $column => $val) {
                if(isset($dictionay[$column]) && $val["index"]!=""){
                    $file.="        if(!is_null(self::\${$column})){\n";
                    $file.="            array_push(\$params2,self::\${$column});\n";
                    $file.="            array_push(\$wenhao2,\"and {$column}=?\");\n";
                    $file.="        }\n";
                    continue;
                }
                $file.="        if(!is_null(self::\${$column})){\n";
                $file.="            array_push(\$params1,self::\${$column});\n";
                $file.="            array_push(\$wenhao1,\"{$column}=?\");\n";
                $file.="        }\n";
            }
            $file.="        \$sql=\"update ".$table["table"]." set \".implode(\",\",\$wenhao1).\" where 1=1 \".implode(\" \",\$wenhao2).\";\";\n";
            $file.="        \$params=array_merge(\$params1,\$params2);\n";
            $file.="        return [\"sql\"=>\$sql,\"params\"=>\$params];\n";
            $file.="    }\n";

            $file.="}\n";
            $file.="?>\n";
            file_put_contents("model/".$table["table"].".php",$file);
        }

        echo '<hr>Success:创建MODEL';
    }
}
?>